package com.example.mall.common;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JwtToken生成的工具类
 *  Created by myc on 2021/4/27
 */
@Component
public class JwtTokenUtil {


        private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
        private static final String CLAIM_KEY_USERNAME = "sub";
        private static final String CLAIM_KEY_CREATED = "created";
        private String secret ="mySecret";
//        @Value("${jwt.expiration}")
        private Long expiration = 604800L;

        /**
         * 根据负责生成JWT的token
         */
        private String generateToken(Map<String,Object> claims){
                return Jwts.builder().setClaims(claims).setExpiration(generateExpirationDate())
                        .signWith(SignatureAlgorithm.HS256,secret)
                        .compact();
        }
        /**
         * 从token中获取JWT中的负载
         */
        private  Claims getClaimsFromToken(String token){
                Claims claims = null;
                try{
                        claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
                } catch (Exception e){
                        LOGGER.info("JWT格式验证失败:{}",token);
                }
                return claims;
        }
        /**
         * 生成token过期时间
         */
        private Date generateExpirationDate(){
                return new Date(System.currentTimeMillis()+expiration*1000);
        }

        /**
         * 从token中获取登录用户名
         */
        public String getUserNameFromToken(String token){
                String username;
                try{
                        Claims claims = getClaimsFromToken(token);
                        username = claims.getSubject();
                }catch (Exception e){
                        username = null;
                }
                return username;
        }
        /**
         * 验证token是否还有效
         *
         * @param  token  客户端传入的token
         * @param  userDetails 从数据库中查询出来的用户信息
         */
        public boolean validateToken(String token, UserDetails userDetails){
                String username = getUserNameFromToken(token);
                return username.equals(userDetails.getUsername())&&!isTokenExpired(token);
        }

        /**
         * 判断是否已经失效
         * @param token
         * @return
         */
        private boolean isTokenExpired(String token) {
                Date expiredDate = getExpireDateFromToken(token);
                return expiredDate.before(new Date());
        }

        /**
         * 从token中获取过期时间
         * @param token
         * @return
         */
        private Date getExpireDateFromToken(String token) {
                Claims claims = getClaimsFromToken(token);
                return claims.getExpiration();
        }
        /**
         * 根据用户信息生成token
         */
        public String generateToken(UserDetails userDetails){
                Map<String,Object> claims = new HashMap<>();
                claims.put(CLAIM_KEY_USERNAME,userDetails.getUsername());
                claims.put(CLAIM_KEY_CREATED,new Date());
                return generateToken(claims);
        }
        /**
         * 判断token是否可以被刷新
         */
        public boolean canRefresh(String token) {
                return !isTokenExpired(token);
        }

        /**
         * 刷新token
         */
        public String refreshToken(String token) {
                Claims claims = getClaimsFromToken(token);
                claims.put(CLAIM_KEY_CREATED, new Date());
                return generateToken(claims);
        }

}
